#ifdef SU1
#define _GLIBCXX_DEBUG
#endif

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define sz(a) (int) (a).size()
#define all(a) (a).begin(), (a).end()
#define ft first
#define sc second
#define x first
#define y second

template<typename X> inline X abs(const X& a) { return a < 0 ? -a : a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = int(2e9) + 300;
const li INF64 = li(1e18);
const ld PI = acosl(ld(-1));
const ld EPS = 1e-9;

const int N = 1000 + 3;
const int K = 120 + 3;

int n, m, s, T;
vector<pt> g[N];
int good[N], cost[N];
int start, finish;
int dist[K][K];
int d[K][K];
int num[N];

inline bool read()
{
	if (scanf("%d%d%d%d", &n, &m, &s, &T) != 4) return false;
	
	forn(i, n)
	{
		num[i] = -1;
		g[i].clear();
	}
	
	forn(i, m)
	{
		int a, b, w;
		assert(scanf("%d%d%d", &a, &b, &w) == 3);
		--a, --b;
		g[a].pb(mp(b, w));
		g[b].pb(mp(a, w));
	}
	
	forn(i, s)
	{
		assert(scanf("%d%d", &good[i], &cost[i]) == 2);
		good[i]--;
		num[good[i]] = i;
	}
	
	assert(scanf("%d%d", &start, &finish) == 2);
	--start, --finish;
	
	if (num[finish] == -1)
	{
		good[s] = finish;
		num[finish] = s;
		cost[s] = 0;
		s++;
	}
	
	return true;
}

int z[N];

void bfs (int idx)
{
	int vstart = good[idx];
	
	queue<int> q;
	q.push(vstart);
	
	forn(i, n) z[i] = INF;
	z[vstart] = 0;
	
	while (!q.empty())
	{
		int v = q.front();
		q.pop();
		
		forn(i, sz(g[v]))
		{
			int to = g[v][i].ft, w = g[v][i].sc;
			if (z[to] > z[v] + w)
			{
				z[to] = z[v] + w;
				q.push(to);
			}
		}
	}
	
	forn(i, s) dist[idx][i] = z[good[i]];
}

inline void solve()
{
	forn(i, s) bfs(i);
	
	forn(i, s + 1) forn(j, s + 1) d[i][j] = INF;
	d[num[start]][s] = 0;
	
	//forn(i, s) cerr << cost[i] << ' '; cerr << endl;
	//forn(i, s) cerr << good[i] << ' '; cerr << endl;
	//forn(i, n) cerr << num[i] << ' '; cerr << endl;
	//forn(i, s) { forn(j, s) cerr << dist[i][j] << ' '; cerr << endl; }
	
	queue<pt> q;
	q.push(mp(num[start], s));
	
	while (!q.empty())
	{
		int v = q.front().ft, prev = q.front().sc;
		q.pop();
		
		int curT = (prev == s ? 0 : (T - dist[prev][v]));
		
		//cerr << v << ' ' << prev << ' ' << curT << endl;
			
		forn(i, s)
		{
			if (dist[v][i] > T) continue;
			
			if (dist[v][i] >= curT)
			{
				int need = dist[v][i] - curT;
				int w = need * cost[v];
				if (d[i][s] > d[v][prev] + w)
				{
					d[i][s] = d[v][prev] + w;
					q.push(mp(i, s));
				}
			}
			
			int w = (T - curT) * cost[v];
			if (d[i][v] > d[v][prev] + w)
			{
				d[i][v] = d[v][prev] + w;
				q.push(mp(i, v));
			}
		}
	}
	
	int ans = INF;
	forn(i, s + 1) ans = min(ans, d[num[finish]][i]);
	
	cout << ans << endl;
}

int main()
{
#ifdef SU1
	assert(freopen("input.txt", "rt", stdin));
//	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(5);
	
	int testCount;
	cin >> testCount;
	
	forn(test, testCount)
	{
		assert(read());
		solve();
	}
	
#ifdef SU1
	cerr << "=== TIME : " << clock() << " ===" << endl;
#endif
	return 0;
}
